package com.fsy.its.netty.handler;

import com.fsy.its.entity.Dtu;
import com.fsy.its.netty.dtu.DtuIdDecoder;
import com.fsy.its.netty.msg.BaseMsg;
import com.fsy.its.netty.msg.FireStateMsg;
import com.fsy.its.netty.msg.MsgHead;
import com.fsy.its.service.AlarmService;
import com.fsy.its.service.DtuService;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Slf4j
@Component
@Scope("prototype")
public class ItsMessageHandler extends ChannelInboundHandlerAdapter {

    @Autowired
    private DtuService dtuService;

    @Autowired
    private AlarmService alarmService;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception {
        BaseMsg msg = (BaseMsg)obj;
        log.info("Receive msg: {}", msg);

        //对发送数据进行答复确认
        if( msg.getHead().getCommand() == MsgHead.CMD_SEND ) {
            BaseMsg replay = new BaseMsg();
            replay.getHead().setSequence(msg.getHead().getSequence());
            replay.getHead().setVersion(msg.getHead().getVersion());
            replay.getHead().setTime(LocalDateTime.now());
            replay.getHead().setSrcAddr(msg.getHead().getDstAddr());
            replay.getHead().setDstAddr(msg.getHead().getSrcAddr());
            replay.getHead().setCommand(MsgHead.CMD_RESPONSE);
            ChannelFuture f = ctx.writeAndFlush(replay);
            f.addListener((ChannelFutureListener) channelFuture -> {
                if (!channelFuture.isSuccess()) {
                    log.error("Send message failed: ", channelFuture.cause());
                } else {
                    //log.info("Send successfully");
                }
            });
        }

        if( msg instanceof FireStateMsg ) {
            if( ctx.channel().hasAttr(DtuIdDecoder.DTU_KEY) ) {
                Dtu dtu = ctx.channel().attr(DtuIdDecoder.DTU_KEY).get();
                alarmService.doAlarm(dtu, (FireStateMsg)msg);
            }
        }

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        if( ctx.channel().hasAttr(DtuIdDecoder.DTU_KEY) ) {
            Dtu dtu = ctx.channel().attr(DtuIdDecoder.DTU_KEY).get();
            dtuService.dtuOnline(dtu);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        if( ctx.channel().hasAttr(DtuIdDecoder.DTU_KEY) ) {
            Dtu dtu = ctx.channel().attr(DtuIdDecoder.DTU_KEY).get();
            dtuService.dtuOffline(dtu);
        }
    }
}
